/*
 * Licensed to the 南京汇海交通科技有限公司
 *
 * Copyright (c) 2025.
 * All rights reserved.
 *
 * 本软件属南京汇海交通科技有限公司所有，在未获得南京汇海交通科技有限公司正式授权情况下，任何企业和个人，不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
 */
package com.chframework.boot.core.response.result;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.chframework.common.context.SpringContextHolder;
import com.chframework.common.exception.ApplicationException;
import com.chframework.common.extend.HttpsHelper;
import com.chframework.common.web.IApiResult;
import org.springframework.lang.NonNull;

import java.text.MessageFormat;
import java.util.Objects;

/**
 * open api 响应对象
 */
public final class OpenApiResult extends ApiResult<Object> {

    private static final ObjectMapper OBJECT_MAPPER;

    static {
        OBJECT_MAPPER = SpringContextHolder.getBean(ObjectMapper.class);
    }

    private OpenApiResult() {
        super();
    }

    /**
     * 构建open api的在外网的响应对象
     */
    @NonNull
    public static OpenApiResult createResult(@NonNull IApiResult<?> apiResult) throws ApplicationException {
        try {
            OpenApiResult openApiResult = new OpenApiResult();
            openApiResult.requestId = apiResult.getRequestId();
            // openApiResult.success
            openApiResult.result = apiResult.getResult();
            // openApiResult.timestamp
            openApiResult.code = apiResult.getCode();
            openApiResult.message = apiResult.getMessage();

            return openApiResult;
        } catch (Exception e) {
            throw new ApplicationException(e);
        }
    }

    /**
     * 将原始数据加密
     */
    public OpenApiResult encrypt(@NonNull String secretKey) throws ApplicationException {
        try {
            if (Objects.isNull(this.result)) {
                return this;
            }

            String apiResultJson;
            if (this.result instanceof Character) {
                apiResultJson = ((Character) this.result).toString();
            } else if (this.result instanceof CharSequence) {
                apiResultJson = String.valueOf(this.result);
            } else {
                apiResultJson = OBJECT_MAPPER.writeValueAsString(this.result);
            }
            this.result = HttpsHelper.encrypt(apiResultJson, secretKey);

            return this;
        } catch (Exception e) {
            throw new ApplicationException(e);
        }
    }

    /**
     * 获取原始数据
     */
    public OpenApiResult decrypt(@NonNull String secretKey) throws ApplicationException {
        try {
            String plainText = HttpsHelper.decrypt((String) this.result, secretKey);
            if (JSONUtil.isTypeJSON(plainText)) {
                this.result = JSONUtil.parse(plainText);
            } else if (NumberUtil.isNumber(plainText)) {
                this.result = Convert.toNumber(plainText);
            } else if (ImmutableList.of("true", "false").contains(plainText)) {
                this.result = Boolean.valueOf(plainText);
            } else {
                this.result = plainText;
            }

            return this;
        } catch (Exception e) {
            throw new ApplicationException(e);
        }
    }

    @Override
    public String toString() {
        try {
            return OBJECT_MAPPER.writeValueAsString(this);
        } catch (Exception ignored) {
            return MessageFormat.format("OpenApiResult{requestId='{0}', code='{1}', message='{2}', success={3}, result={4}, timestamp={5}}",
                    requestId, code, message, success, result, timestamp);
        }
    }

}
